/*
 * © 2024 huayunliufeng保留所有权利, 依据MIT许可证发布。
 * 请勿更改或删除版权声明或此文件头。
 * 此代码是免费软件, 您可以重新分发和/或修改它。
 * 开源是希望它有用, 但不对代码做任何保证。
 * 如有疑问请联系: huayunliufeng@163.com
 */

package io.github.huayunliufeng.dbinfo.dbinfo;

import io.github.huayunliufeng.common.utils.HylfDataUtil;
import io.github.huayunliufeng.common.utils.HylfFunUtil;
import io.github.huayunliufeng.dbinfo.model.BestRowIdentifierInfo;
import lombok.extern.slf4j.Slf4j;

import java.sql.Connection;
import java.sql.ResultSet;
import java.util.List;
import java.util.Map;

/**
 * 检索表中唯一标识一行的最佳列集的描述。它们是按scope排序的。
 *
 * @author zhongq
 * @datetime 2024/3/29 14:50
 */
@Slf4j
public class ObtainBestRowIdentifierInfo extends ObtainDbInfo {
    private static Map<Connection, ObtainBestRowIdentifierInfo> obtainBestRowIdentifierInfoMap = null;

    private Map<String, List<BestRowIdentifierInfo>> bestRowIdentifierInfoMap = null;

    protected ObtainBestRowIdentifierInfo(Connection conn) {
        super(conn);
    }

    public static ObtainBestRowIdentifierInfo build(Connection conn) {
        obtainBestRowIdentifierInfoMap = HylfFunUtil.mapAddValue(obtainBestRowIdentifierInfoMap, conn, () -> new ObtainBestRowIdentifierInfo(conn));
        return obtainBestRowIdentifierInfoMap.get(conn);
    }

    /**
     * 检索表中唯一标识一行的最佳列集的描述。它们是按scope排序的。
     *
     * @param catalog  目录名称;必须与存储在数据库中的目录名称匹配;“”检索那些没有目录的;null表示不应使用目录名称来缩小搜索范围
     * @param schema   模式名;必须与存储在数据库中的模式名称匹配;""检索那些没有模式的;null表示不应该使用模式名称来缩小搜索范围
     * @param table    表名;必须匹配存储在数据库中的表名
     * @param scope    利益范围;使用与scope相同的值
     * @param nullable 包括可空的列。
     * @return 每行是一个列描述
     */
    public List<BestRowIdentifierInfo> getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) {
        String logFormat = "获取数据库BestRowIdentifier失败。[catalog = {}, schema = {}, table = {}, scope = {}, nullable = {}]";
        return HylfFunUtil.methodVoidReturnExec(() -> {
            String key = String.join("-", catalog, schema, table);
            bestRowIdentifierInfoMap = HylfFunUtil.mapAddValue(bestRowIdentifierInfoMap, key, () -> {
                ResultSet resultSet = HylfFunUtil.methodVoidReturnExec(
                        () -> databaseMetaData.getBestRowIdentifier(catalog, schema, table, scope, nullable)
                        , logFormat, catalog, schema, table, scope, nullable);
                List<BestRowIdentifierInfo> bestRowIdentifierInfoList = HylfDataUtil.autoSetValue(resultSet, BestRowIdentifierInfo.class);
                HylfFunUtil.autoClose(resultSet);
                return bestRowIdentifierInfoList;
            });
            return bestRowIdentifierInfoMap.get(key);
        });
    }

    /**
     * 检索表中唯一标识一行的最佳列集的描述。它们是按scope排序的。
     *
     * @param table    表名;必须匹配存储在数据库中的表名
     * @param scope    利益范围;使用与scope相同的值
     * @param nullable 包括可空的列。
     * @return 每行是一个列描述
     */
    public List<BestRowIdentifierInfo> getBestRowIdentifier(String table, int scope, boolean nullable) {
        return getBestRowIdentifier(getCatalog(), getSchema(), table, scope, nullable);
    }
}
